
package com.fit.user.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;

/**
 * 要想让datasource真正能在iReport中应用,就必须实现JRDataSource这个接口.
 * 该接口只有两个方法:一个是getFieldValue,该方法用来取datasource中某一记录的
 * 某一字段的值;另一个是next,用来控制游标加一,并检查游标是否到达记录集的末尾.
 * 
 * @author ZhaoClin
 * @version 1.0.0
 * 
 */
public class AppJRDataSource implements JRDataSource {

	private List<Object> objects = new ArrayList<Object>();
	private int index = -1;

	public AppJRDataSource() {
	}

	/**
	 * 初始化构造方法
	 * 
	 * @param objects
	 */
	public AppJRDataSource(List<Object> objects) {
		this.init(objects);
	}

	/**
	 * 初始化方法
	 * 
	 * @param objects
	 */
	public void init(List<Object> objects) {
		if (objects != null) {
			this.objects = objects;
		}
	}

	/**
	 * 根据字段信息到datasource中取该字段的值
	 */
	public Object getFieldValue(JRField jrfield) throws JRException {
		String jrFieldName = jrfield.getName();
		
		Object object = this.objects.get(index);
		
		
		Class<?> cls = object.getClass();
		Field[] objFields = cls.getDeclaredFields();
		for (int i = 0; i < objFields.length; i++) {
			Field objField = objFields[i];
			String fieldName = objField.getName();
			int idx = jrFieldName.indexOf(".");
			if (fieldName.equals(jrFieldName)) {
				String getterName = "get"
						+ fieldName.substring(0, 1).toUpperCase()
						+ fieldName.substring(1);
				try {
					Method getter = cls.getDeclaredMethod(getterName,
							new Class[0]);
					return getter.invoke(object, new Object[0]);
				} catch (Exception e) {
					return null;
				}
			} else if (idx > 0 && jrFieldName.startsWith(fieldName)) {
				String refJrFieldName = jrFieldName.substring(idx + 1);
				String getterName = "get"
						+ fieldName.substring(0, 1).toUpperCase()
						+ fieldName.substring(1);
				try {
					Method getter = cls.getDeclaredMethod(getterName,
							new Class[0]);
					Object refObject = getter.invoke(object, new Object[0]);
					Class<?> refCls = objField.getType();
					Field[] refObjFields = refCls.getDeclaredFields();
					for (int j = 0; j < refObjFields.length; j++) {
						Field refObjField = refObjFields[j];
						String refFieldName = refObjField.getName();
						if (refFieldName.equals(refJrFieldName)) {
							String refGetterName = "get"
									+ refFieldName.substring(0, 1)
											.toUpperCase()
									+ refFieldName.substring(1);
							Method refGetter = refCls.getDeclaredMethod(
									refGetterName, new Class[0]);
							return refGetter.invoke(refObject, new Object[0]);
						}
					}
				} catch (Exception e) {
					return null;
				}
			}
		}
		return null;
	}

	/**
	 * 判断是否还有下一条记录
	 */
	public boolean next() throws JRException {
		index++;
		return index < this.objects.size();
	}
}
